package com.cloudptt.wp.ui.call.single.fv;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

import com.cloudptt.api.comm.CommDlg;
import com.cloudptt.api.pjsip.api.SipManager;
import com.cloudptt.api.product.ISuperCallOperator;
import com.cloudptt.api.product.Product;
import com.cloudptt.api.product.func.call.CallAttr;
import com.cloudptt.api.product.func.call.CallConst;
import com.cloudptt.api.product.func.call.CallListener;
import com.cloudptt.api.product.func.call.group.fsm.video.GroupCallMemberInfo;
import com.cloudptt.api.product.func.call.single.LaunchCallInfo;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.wp.R;
import com.cloudptt.wp.SysApplication;
import com.cloudptt.wp.ui.call.single.CallActivity;
import com.cloudptt.wp.ui.call.VideoCallOp;
import com.mcptt.db.model.AddrInfo;

import java.util.List;

public class FloatWindowService extends Service implements CallListener, VideoCallOp,CloseOp {
	public static final int MSGID_CALL = 1;
	public static final int MSGID_MEDIA = 2;
	public static final int HEIGHT_VOICE = 157;
	public static final int HEIGHT_VIDEO = 239;
	public static final int WIDTH = 157;
	private WindowManager windowManager;
	private WindowManager.LayoutParams layoutParams;

	private View floatView = null;
	private TextView tipTextView;

	private String curCallKey = null;
	private LaunchCallInfo callInfo = null;
	private AddrInfo fromAddressInfo = null;
	private Product product = null;
	private MsgHandler msgHandler = null;
	private SurfaceView surfaceInVideo = null;
	private SurfaceView surfacePreview = null;
//	private VideoSurfaceHandler previewHandler = null;

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.debug(this.getClass(), "FloatWindowService onCreate");
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.debug(this.getClass(), "onBind");
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.debug(this.getClass(), "onStartCommand intent = " + intent);
		if(intent == null)
		{
			return super.onStartCommand(intent, flags, startId);
		}
		this.callInfo = (LaunchCallInfo)intent.getSerializableExtra(SipManager.EXTRA_PRIVACY_CALL_INFO);
		this.fromAddressInfo = (AddrInfo)intent.getSerializableExtra(SipManager.EXTRA_PRIVACY_CALL_USER);
		Log.debug(this.getClass(),"onStartCommand callInfo = " + callInfo + " fromAddressInfo = " + fromAddressInfo);
		SysApplication app = ((SysApplication) getApplicationContext());
		if(app != null)
		{
			product = app.getProduct();
			if(product != null
					&& callInfo != null)
			{
				product.setSingleCallListener(this);
				this.curCallKey = callInfo.getCallKey();
			}
		}

		showFloatingView(callInfo, fromAddressInfo);
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.debug(this.getClass(), "onDestroy");
		super.onDestroy();
	}

	private boolean checkFloatPermission(Context context){
		if(Build.VERSION.SDK_INT >= 23){
			boolean result = false;
			result = Settings.canDrawOverlays(context);
			return result;
		}else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){//4.4-5.1
			return true;
		}
		return true;
	}

	public void showFloatingView(LaunchCallInfo callInfo, AddrInfo userInfo){
		Log.debug(this.getClass(), "showFloatingView");
		this.callInfo = callInfo;
		this.curCallKey = callInfo.getCallKey();
		this.fromAddressInfo =  userInfo;

		if(checkFloatPermission(getApplicationContext())){
			windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
			this.msgHandler = new MsgHandler(this.getMainLooper());

			int callType = callInfo.getCallType();
			int callState = callInfo.getCallState();
			boolean hasVideo = callInfo.isHasVideo();
			Log.debug(this.getClass(), "showFloatingView callType = "+callType + " callState = "+callState + " hasVideo = " + hasVideo);
			try {
				updateUi(callType,callState,hasVideo);
				String callKey = callInfo.getCallKey();
				int mediaState = callInfo.getCallMediaState();
				updateMediaStatus(callKey,mediaState);
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
	}

	private void updateUi(int callType,int callState,boolean hasVideo)
	{
		Log.debug(this.getClass(), "updateUi callType = "+callType + "callState = "+callState + " hasVideo = " + hasVideo);
		int heightVal = this.getHeightVal(hasVideo);
		if(callType == CallAttr.CallType_Private)
		{
			layoutParams = getLayoutParams(WIDTH,heightVal);

			LayoutInflater inflater = LayoutInflater.from(this);
			floatView = inflater.inflate(R.layout.float_window, null, false);

			ImageView callTypeIv= (ImageView) floatView.findViewById(R.id.callTypeIv);
			tipTextView = (TextView) floatView.findViewById(R.id.tipTextView);

			if(hasVideo)
			{
				callTypeIv.setVisibility(View.GONE);

				surfaceInVideo = (SurfaceView)
						floatView.findViewById(R.id.surfaceInVideo);
				surfaceInVideo.setZOrderMediaOverlay(true);
//				surfaceInVideo.getHolder().addCallback(this);

				surfacePreview = (SurfaceView)
						floatView.findViewById(R.id.surfacePreview);
				surfacePreview.setZOrderMediaOverlay(true);
				surfacePreview.setZOrderOnTop(true);
//				previewHandler = new VideoSurfaceHandler(this);
//				surfacePreview.getHolder().addCallback(previewHandler);
				surfacePreview.setVisibility(View.VISIBLE);

				surfacePreview.setVisibility(View.INVISIBLE);

				if(callState == CallConst.CallState_ConnectingState) {
					surfaceInVideo.setVisibility(View.GONE);
				}
				else {
					surfaceInVideo.setVisibility(View.INVISIBLE);
				}
			}
			else
			{
				callTypeIv.setVisibility(View.VISIBLE);
			}

			WindowManager.LayoutParams lp;
			lp = getLayoutParams(WIDTH, heightVal);
			windowManager.addView(floatView, lp);

			FloatingViewTouchListener listener = new FloatingViewTouchListener(this, floatView,layoutParams,this);
			floatView.setOnTouchListener(listener);
		}
	}

	private int getHeightVal(boolean isHasVideo)
	{
		if(isHasVideo)
		{
			return HEIGHT_VIDEO;
		}
		return HEIGHT_VOICE;
	}

	private WindowManager.LayoutParams getLayoutParams(int width,int heith)
	{
		WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
			lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
		}else
		{
			lp.type = WindowManager.LayoutParams.TYPE_PHONE;
		}

		lp.format = PixelFormat.RGBA_8888;
		lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
		lp.gravity = Gravity.LEFT | Gravity.TOP;
		lp.width = width;
		lp.height = heith;
		lp.x = 300;
		lp.y = 50;

		return lp;
	}

//	@Override
//	public boolean isVidOk()
//	{
//		Log.debug(this.getClass(),"isVidOk product = " + product);
//		if(!callInfo.isHasVideo())
//		{
//			return false;
//		}
//		if (product == null) {
//			SysApplication app = ((SysApplication) getApplicationContext());
//			product = app.getProduct();
//
//		}
//		if (product != null) {
//			ISuperCallOperator op = product.getSuperCallOperator();
//			String callIdStr = callInfo.getCallIdStr();
//			return op.getCallOperator().isVidOk(callIdStr);
//		}
//		return false;
//	}
//
//	@Override
//	public void startPreView(Surface surface) {
//		if(!callInfo.isHasVideo())
//		{
//			return;
//		}
////        startPreView1(vidPrevParam);
//		if (product == null) {
//			SysApplication app = ((SysApplication) getApplicationContext());
//			product = app.getProduct();
//		}
//		if (product != null) {
//			ISuperCallOperator op = product.getSuperCallOperator();
//			String callIdStr = callInfo.getCallIdStr();
//			op.getCallOperator().startPreView(callIdStr,surface);
//		}
//
//	}
//
//	@Override
//	public void stopPreView() {
//		Log.debug(this.getClass(),"stopPreView");
//		if(!callInfo.isHasVideo())
//		{
//			return;
//		}
//		if (product == null) {
//			SysApplication app = ((SysApplication) getApplicationContext());
//			product = app.getProduct();
//		}
//		if (product != null) {
//			ISuperCallOperator op = product.getSuperCallOperator();
//			String callIdStr = callInfo.getCallIdStr();
//			op.getCallOperator().stopPreView(callIdStr);
//		}
//	}
//
//	@Override
//	public void setRemoteView(Surface surface) {
//		if(!callInfo.isHasVideo())
//		{
//			return;
//		}
//		if (product == null) {
//			SysApplication app = ((SysApplication) getApplicationContext());
//			product = app.getProduct();
//		}
//		if (product != null) {
//			ISuperCallOperator op = product.getSuperCallOperator();
//			String callIdStr = callInfo.getCallIdStr();
//			op.getCallOperator().setRemoteView(callIdStr,surface);
//		}
//	}
@Override
public void setSurfaceView(SurfaceView surfaceInVideo, SurfaceView surfacePreview) {
	Log.debug(this.getClass(),"setRemoteView");
	if(!callInfo.isHasVideo())
	{
		return;
	}
	if (product == null) {
		SysApplication app = ((SysApplication) getApplicationContext());
		product = app.getProduct();
	}
	if (product != null) {
		ISuperCallOperator op = product.getSuperCallOperator();
		String callIdStr = callInfo.getCallIdStr();
		op.getCallOperator().setSurfaceView(callIdStr,surfaceInVideo,surfacePreview);
	}
}
	@Override
	public void setCaptureOrient(int orient)
	{
		Log.debug(this.getClass(),"setCaptureOrient");
		if(!callInfo.isHasVideo())
		{
			return;
		}
		if (product == null) {
			SysApplication app = ((SysApplication) getApplicationContext());
			product = app.getProduct();
		}
		if (product != null) {
			ISuperCallOperator op = product.getSuperCallOperator();
			op.getCallOperator().setCaptureOrient(orient);
		}
	}
//	@Override
//	public void incomingCall(String callKey,AddrInfo incomingInfo)
//	{}
	@Override
	public void updateCallState(String callKey, int callState,boolean isHasVideo) {
		// TODO Auto-generated method stub
		Log.debug(this.getClass(), "updateCallState callKey = " + callKey + " callState = " + callState + " isHasVideo = " + isHasVideo + " callInfo = " + callInfo);
		this.callInfo.setCallState(callState);
		if(msgHandler != null)
		{
			Message msg = msgHandler.obtainMessage(MSGID_CALL);
			msg.arg1 = callState;
			msg.sendToTarget();
		}
	}

	@Override
	public void notifyErrStr(String callKey, String errStr) {

	}

	@Override
	public void updateCallDuration(String callKey,String secStr) {
		// TODO Auto-generated method stub
		tipTextView.setText(secStr);
	}
	@Override
	public void updateMicMute(String callKey, boolean isMicMute) {

	}
	@Override
	public void updateMediaStatus(String callKey, int mediaStatus)
	{
		Log.debug(this.getClass(),"updateMediaStatus mediaStatus = " + mediaStatus);
		this.callInfo.setCallMediaState(mediaStatus);
		Message msg = msgHandler.obtainMessage(MSGID_MEDIA);
		msg.arg1 = mediaStatus;
		msg.sendToTarget();
	}
	@Override
	public void updateVideoEvent(String callKey)
	{}
	@Override
	public void updateGroupCallMemberInfoList(List<GroupCallMemberInfo> groupCallMemberInfoList)
	{}
//	@Override
//	public boolean onKey(View v, int keyCode, KeyEvent event) {
//		if (keyCode == KeyEvent.KEYCODE_BACK) {
//			// �����ذ����¼�
//			// ����true��ʾ�Ѵ�����¼�
//			doClearAndCloseSelf();
//			return true;
//		}
//		return false;
//	}

	@Override
	public void doClearAndCloseSelf() {
		Log.debug(this.getClass(), "doClose");
		if(surfaceInVideo != null)
		{
			surfaceInVideo.getHolder().addCallback(null);
			surfaceInVideo.destroyDrawingCache();
		}
//		if(previewHandler != null)
//		{
//			previewHandler.updateVideoPreview(null);
//		}
		if(surfacePreview != null)
		{
			surfacePreview.getHolder().addCallback(null);
			surfacePreview.destroyDrawingCache();
			surfacePreview = null;
		}
//		previewHandler = null;
//		stopPreView();
		if(windowManager == null)
		{
			windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		}
		Log.debug(this.getClass(), "doClose isAttachedToWindow floatView != null = " + (floatView != null) + " floatView.isAttachedToWindow() = " + floatView.isAttachedToWindow());
		if(floatView != null && floatView.isAttachedToWindow()){
			Log.debug(this.getClass(), "isAttachedToWindow true");
			windowManager.removeView(floatView);
		}
		stopSelf();
	}

	@Override
	public  void switchToActivity(){
		Log.debug(this.getClass(), "switchToActivity");
		if(product == null){
			SysApplication app = ((SysApplication) getApplicationContext());
			product = app.getProduct();
		}
		product.setShowFloatWin(curCallKey, false);
		Intent intent = new Intent(this, CallActivity.class);
		intent.putExtra(SipManager.EXTRA_PRIVACY_CALL_INFO, callInfo);
		intent.putExtra(SipManager.EXTRA_PRIVACY_CALL_USER, fromAddressInfo);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
		startActivity(intent);
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
		Log.debug(this.getClass(), "surfaceChanged  " + w + "*" + h);
		updateVideoWindow(true);
	}

	public void surfaceCreated(SurfaceHolder holder) {
		Log.debug(this.getClass(), "surfaceCreated  ");
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		Log.debug(this.getClass(), "surfaceDestroyed  " );
		updateVideoWindow(false);
	}
	private void updateVideoWindow(boolean show) {
		Log.debug(this.getClass(), "updateVideoWindow show = " + show);
//		Log.debug(this.getClass(),"updateVideoWindow isVidOk = " + isVidOk());
//		if(isVidOk())
//		{
//			try {
//				if(callInfo.getCallType() == CallAttr.CallType_Private)
//				{
//					Log.debug(this.getClass(),"updateVideoWindow 1 ");
//					setRemoteView(surfaceInVideo.getHolder().getSurface());
//				}
//			} catch (Exception e) {
//				Log.debug(this.getClass(), "updateVideoWindow  e = " + e);
//			}
//		}
	}

	private class MsgHandler extends Handler
	{
		public MsgHandler(Looper loop)
		{
			super(loop);
		}
		public void handleMessage(Message msg)
		{
			Log.debug(this.getClass(), "handleMessage msg.what  " + msg.what + " msg.arg1 = " + msg.arg1);
			if(msg.what == MSGID_CALL) {
				switch (msg.arg1) {
					case 0:
						String errStr = msg.obj.toString();
						CommDlg.showShortToast(FloatWindowService.this, errStr);
						break;
					case CallConst.CallState_InitState:
						doClearAndCloseSelf();
						break;

					case CallConst.CallState_Activite:
						tipTextView.setText("00:00");
						break;
					default:
						break;
				}
			}
			else if(msg.what == MSGID_MEDIA
					&& msg.arg1 == CallConst.CallMediaState_Active) {
//				boolean isOk = isVidOk();
//				Log.debug(this.getClass(),"updateMediaStatus isOk = " + isOk);
//				if (isOk) {
//					/* Set capture orientation according to current
//					 * device orientation.
//					 */
////            onConfigurationChanged(getResources().getConfiguration());
//					/* If there's incoming video, display it. */
//					if(callInfo.isHasVideo()
//						&& callInfo.getCallType() == CallAttr.CallType_Private)
//					{
//						previewHandler.updateVideoPreview(surfacePreview.getHolder());
//						surfacePreview.getLayoutParams().width = 1;
//						surfacePreview.getLayoutParams().height = 1;
//						surfacePreview.requestLayout();
//
//						surfaceInVideo.setVisibility(View.VISIBLE);
//						surfacePreview.setVisibility(View.VISIBLE);
//					}
//				}
			}
		};
	}
}
